<?php


namespace app\user\controller;


use app\common\controller\Common;
use app\common\model\Cards;
use app\common\model\PayOrder;
use app\common\model\ReferralCode;
use app\common\model\SharingOrder;
use app\common\model\SharingReceiver;
use think\Exception;
use think\facade\Log;
use think\Db;
use Wxpay\Wxpay;

class Order extends Common
{
    //生成订单
    public function getOrder()
    {
        $openid = request()->param('openid');
        if ($openid) {
            $repo = Db::query("SELECT * FROM pay_order WHERE memid in(SELECT memid FROM member WHERE openid='" . $openid . "') AND type=1 AND o_status in(-1,1) LIMIT 0,1");
            if (count($repo) > 0) {
                foreach ($repo as $value) {
                    $retdatas = [
                        'price' => $value['total_fee'],
                        'body' => $value['body'],
                        'poid' => $value['poid'],
                        'card_no' => $value['o_card_no'],
                    ];
                }
                return $this->okJson('查找到原订单', $retdatas);
            }
            $res = $this->buildOrder($openid);
            if ($res['code'] == 0) {
                return $this->okJson($res['msg'], $res['data']);
            }
            return $this->errJson($res['msg']);
        }
        return $this->errJson('参数错误');
    }

    public function renewal()
    {
        $openid = request()->param('openid');
        $repo = Db::query("SELECT * FROM pay_order WHERE memid in(SELECT memid FROM member WHERE openid='" . $openid . "') AND type=2 AND o_status in(-1,1) LIMIT 0,1");
        if (count($repo) > 0) {
            foreach ($repo as $value) {
                $retdatas = [
                    'price' => $value['total_fee'],
                    'body' => $value['body'],
                    'poid' => $value['poid'],
                    'card_no' => $value['o_card_no'],
                ];
            }
            return $this->okJson('查找到原订单', $retdatas);
        }
        //复制创建订单
        $PayOrder = new PayOrder();
        $rePayaOrder = $PayOrder->where(['openid' => $openid, 'o_status' => 2])->find();
        if ($rePayaOrder) {
            $PayOrderdatas = [
                'memid' => $rePayaOrder->memid,
                'o_no' => $this->build_order_no(),
                'o_card_no' => $rePayaOrder->o_card_no,
                'total_fee' => $rePayaOrder->total_fee,
                'body' => $rePayaOrder->body,
                'o_mobile' => $rePayaOrder->o_mobile,
                'openid' => $openid,
                'type' => 2,
                'ctime' => time()
            ];
            $ret = PayOrder::create($PayOrderdatas);
            if ($ret) {
                $retdatas = [
                    'price' => $ret->total_fee,
                    'body' => $ret->body,
                    'poid' => $ret->poid,
                    'card_no' => $ret->o_card_no
                ];
                return $this->okJson('创建成功', $retdatas);
            }

        }
        return $this->errJson('数据异常');
    }


    //新生成订单
    private function buildOrder($openid)
    {
        //如果会员信息存在，对信息操作
        $member = new \app\common\model\Member();
        $member = $member->where('openid', '=', $openid)->find();
        if (empty($member)) return ['msg' => '数据异常', 'code' => -1];
        $memid = $member->memid;
        $ref_code = $member->ref_code;
        //创建卡片
        $retC = $this->build_card($memid);
        if ($retC['msg']!='ok') return ['msg' => $retC['msg'], 'code' => -1];
        Db::startTrans();
        try {
            $retcards=$retC['CardsObJ'];
            $o_mobile = $member->mobile;
            $member->cards_nember++;
            $member->status = 1;
            $retmem = $member->save();

            //加工订单信息
            $body = $retcards->cate_title;
            $price = $retcards->price;
            $card_no = $retcards->card_no;//卡号
            $reReferralCode = ReferralCode::where(['memid' => $memid, 'status' => 1])->find();
            if ($reReferralCode) {//判断是否分账
                $sharing = 'Y';
                $merid = $reReferralCode->merid;
            } else {
                $merid = null;
                $sharing = 'N';
            }
            $PayOrderdatas = [
                'memid' => $memid,
                'o_no' => $this->build_order_no(),
                'o_card_no' => $card_no,
                'total_fee' => $price,
                'body' => $body,
                'o_mobile' => $o_mobile,
                'openid' => $openid,
                'ctime' => time(),
                'sharing' => $sharing,
                'ref_merid' => $merid//推荐商户id
            ];

            $retPayOrder = PayOrder::create($PayOrderdatas);
            if ($retPayOrder && $retmem) {
                Db::commit();
                $poid = $retPayOrder->poid;
                $retdatas = [
                    'price' => $price,
                    'body' => $body,
                    'poid' => $poid,
                    'card_no' => $card_no
                ];
                return ['msg' => '创建成功', 'code' => 0, 'data' => $retdatas];
            } else {
                Db::rollback();
            }
        } catch (\Exception $exception) {
            Db::rollback();
            return ['msg' => '订单创建失败', 'code' => -1];
        }
    }


    //创建随机分配一张卡片id
    function build_card($memid)
    {
        $cards = new Cards();
        $reCards =$cards->where(['memid'=>$memid,'status'=>1])->find();
        if ($reCards) return ['msg' => 'ok', 'CardsObJ' => $reCards];

        $redis = new \redis();
        $redis->connect('127.0.0.1', 6379);
        $cardsLen = $redis->lLen('cardNos');//判断还有几个卡号
        if ($cardsLen == 0) return ['msg' => '会员卡已售罄,请联系服务中心'];

        $card_no = $redis->rPop('cardNos');//从右出取出卡号

        if (empty($card_no)) return ['msg' => '数据异常,请联系服务中心'];

        $reCards = $cards->where(['status' => -1, 'card_no' => $card_no])->find();
        if (empty($reCards)) return ['msg' => '数据异常,请联系服务中心'];
        $reCards->status = 1;
        $reCards->memid = $memid;
        if ($reCards->save()) {
            return ['msg' => 'ok', 'CardsObJ' => $reCards];
        } else {
            $redis->lPush('cardNos', $card_no);
            return ['msg' => '卡片获取异常，请重试'];
        }
    }

    #微信支付类调用
    public function newpay()
    {
        $poid = request()->param('poid');
        if (is_null($poid) || $poid == "") return $this->errJson('参数错误');

        $rePayorder = Payorder::where('poid', '=', $poid)->find();
        if (empty($rePayorder)) return $this->errJson('订单不存在');

        if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
            $scheme = 'https://';
        } else {
            $scheme = 'http://';
        }
        $host = app()->request->host();
        $n_url = $scheme . $host . '/user/order/notify';

        $pay_sn = $rePayorder['o_no'];//订单号
        $total_fee = $rePayorder['total_fee'];
        $openid = $rePayorder['openid'];
        $body = $rePayorder['body'];
        $spbill_create_ip = $this->get_client_ip();
        $notify_url = $n_url;  #根据不同类型回调地址不同
        $trade_type = 'JSAPI';
        #JSAPI--JSAPI支付（或小程序支付）、
        #NATIVE--Native支付、
        #APP--app支付，
        #MWEB--H5支付，
        #不同trade_type决定了调起支付的方式，请根据支付产品正确上传


        #新的需要参数为六个
        # out_trade_no 商户订单号
        # total_fee    订单总额
        # body         商品描述
        # spbill_create_ip   终端IP
        # notify_url   回调通知地址
        # trade_type   交易类型

        $wxpay = new Wxpay();
        $date = [
            'out_trade_no' => $pay_sn,
            'total_fee' => $total_fee,
            'body' => $body,
            'spbill_create_ip' => $spbill_create_ip,
            'notify_url' => $notify_url,
            'trade_type' => $trade_type
        ];
        #根据 trade_type  类型不同，是否传递openid

        #APP   类型支付调用
        //$res = $wxpay->index($date);

        #JSAPI 类型支付调用
        $res = $wxpay->index($date, $openid, $rePayorder->sharing);

        if ($res) {
            $rePayorder->o_status = 1;
            $rePayorder->uptime = time();
            $rePayorder->save();
            return $this->okJson('下单成功', $res);
        }
        if (!$res) return $this->errJson('下单失败');
        #获得后将对应内容返回前端即可
    }


    /**
     * 分账，账单创建
     * @param $order_o_no
     * @param $merid
     * @param $transaction_id
     * @param $total_fee
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    private function createSharingOrder($order_o_no, $merid, $transaction_id, $total_fee)
    {

        $reSharingReceiver = SharingReceiver::where('merid', '=', $merid)->find();
        if (empty($reSharingReceiver)) {
            Log::write($merid);
            return false;
        }
        $bill_type = $reSharingReceiver->bill_type;//分账金额类型
        $account = $reSharingReceiver->account;//分账账号
        $type = $reSharingReceiver->type;//分账接书方类型
        $amount = $reSharingReceiver->amount;//分账金额
        $name=$reSharingReceiver->name;//商家全称，，或个人真实姓名

        if ($bill_type == 2) {
            $ratio = $reSharingReceiver->ratio;
            $amount = $total_fee - $total_fee * $ratio;
            if (($total_fee * $ratio) > ($total_fee * 0.3)) {
                $amount = $total_fee * 0.3;//最大比例为30%
            }
        }
        $reMerchant =\app\common\model\Merchant::get($merid);
        if (empty($reMerchant)) return false;
        $mername=$reMerchant->mername;//商家店名
        $data = [
            'shor_no' => 'sh' . $this->build_order_no(), //分账单号',
            'receivers_type' => $type, // 分账接收方类型 ,
            'amount' => intval($amount),//分账金额,单位分
            'account' => $account,//分账接收方帐号 ,
            'description' => '青檬通用卡分润',//描述,
            'order_o_no' => $order_o_no, //订单号,
            'merid' => $merid,//商家id,
            'mername'=>$mername,//商家店名
            'name'=>$name,//商家全称，，或个人真实姓名
            //'status'=> ,//分账结果,
            //'close_reason'=> '',//关单原因,
            'time' => time(), //
            'updatetime' => time(),
            'transaction_id' => $transaction_id
        ];
        $reSharingOrder = SharingOrder::create($data);
        if (empty($reSharingOrder)) {
            Log::save();
            return false;
        }
        return true;
    }

    /**
     * 更新支付订单
     * @param $out_trade_no
     * @param $transaction_id
     * @return bool|mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    private function updatePayOrder($out_trade_no, $transaction_id)
    {
        $ret = PayOrder::where('o_no', '=', $out_trade_no)->find();
        if ($ret) {
            $memid = $ret->memid;//用户id
            $PayOrderType = $ret->type; //订单类型 续费2; 新开卡1;
            $merid = $ret->ref_merid; //推荐商户id
            $sharing = $ret->sharing; //订单类型，是否分账
            $o_card_no = $ret->o_card_no;//会员卡号
            $ret->transaction_id = $transaction_id; //支付订单号
            $ret->o_status = 2; //订单状态
            $ret->uptime = time();
            if ($ret->save()) {
                return [
                    'memid' => $memid,
                    'PayOrderType' => $PayOrderType,
                    'sharing' => $sharing,
                    'merid' => $merid,
                    'o_card_no' => $o_card_no
                ];
            }
        }
        return false;
        //异常处理
    }

    /**
     * 更新会员卡
     * @param $PayOrderType
     * @param $memid
     * @param $card_no
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    private function updateCards($PayOrderType, $memid, $card_no)
    {
        //卡的状态，还得完善。
        if ($PayOrderType == 2) {//续费
            $where = ['memid' => $memid, 'card_no' => $card_no];
            $term=12;
        } else {//新开卡
            $where = ['memid' => $memid, 'card_no' => $card_no, 'status' => 1];
            $term=0;
        }
        $Card = Cards::where($where)->find();
        $Card->status = 2;
        $Card->use_time=time();
        $Card->term = $Card->term + $term;
        if ($Card->save()) {
            return true;
        }
        return false;
    }

    /**
     * 更新推荐码
     * @param $memid
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    private function updateReferralCode($memid)
    {
        $reRef = ReferralCode::where(['memid' => $memid, 'status' => 1])->find();
        if ($reRef) {
            $reRef->status = 2;
            if ($reRef->save()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 更新会员状态
     * @param $memid
     * @return bool
     *
     */
    private function updateMember($memid)
    {
        $reMember = \app\common\model\Member::get($memid);
        if ($reMember) {
            $reMember->status = 2;
            return $reMember->save();
        }
        return false;
    }

    //支付成功回调
    public function notify()
    {
        $wxpay = new Wxpay();
        $result = $wxpay->notify();
        #根据拿到的数据 来进行自己的数据逻辑
        if ($result['code'] == 1) {
            $out_trade_no = $result['data']['out_trade_no'];//系统订单号
            $transaction_id = $result['data']['transaction_id'];//微信支付订单号
            $total_fee = $result['data']['total_fee'];//微信支付金额
            Db::startTrans();
            try {
                //更新订单
                $rePayOrder = $this->updatePayOrder($out_trade_no, $transaction_id);
                if ($rePayOrder) {
                    //更新会员卡
                    $reCards = $this->updateCards($rePayOrder['PayOrderType'], $rePayOrder['memid'], $rePayOrder['o_card_no']);
                    //更新会员状态
                    $reMember = $this->updateMember($rePayOrder['memid']);
                    //生成分账，账单
                    if (!is_null($rePayOrder['merid'])){
                        //更新推荐表
                        $reReferralCode = $this->updateReferralCode($rePayOrder['memid']);
                        //创建分账账单
                        $reSharingOrder = $this->createSharingOrder($out_trade_no, $rePayOrder['merid'], $transaction_id, $total_fee);
                        if($reReferralCode && $reSharingOrder) {
                            $reSharingOrderFlag=true;
                        }else{
                            $reSharingOrderFlag=false;
                        }
                    }else{
                        $reSharingOrderFlag=true;
                    }

                    if ($reCards && $reReferralCode && $reMember&&$reSharingOrderFlag) {
                        Db::commit();
                        return $result['str'];
                    } else {
                        Db::rollback();
                    }
                }
            } catch (\Exception $exception) {
                file_put_contents('./error.txt', json_encode($rePayOrder, JSON_UNESCAPED_UNICODE) . "\n", FILE_APPEND);
                Db::rollback();
            }
            exit; //中断
        }
        return $result['str'];
        //异常处理

    }


}
